//////////////////////////////////////////////
// PbsMaterialInfo.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkAstraeus
{
	enum class ONE_CHANNEL_PACK ;
	enum class THREE_CHANNEL_PACK ;
}

namespace nkGraphics
{
	class Camera ;
	class Texture ;
}

/// Includes ---------------------------------

// nkAstraeus
#include "../../ShaderLibs/ShadowMapping/Data/ShadowMapParameters.h"

#include "Enums/PbsModel.h"

// nkMaths
#include <NilkinsMaths/Algebra/Vector.h>

// nkMemory
#include <NilkinsMemory/Containers/String.h>

/// Class ------------------------------------

namespace nkAstraeus
{
	struct PbsMaterialInfo final
	{
		// Structures
		nkMaths::Vector _lightDir = nkMaths::Vector(1.f, -1.f, 1.f) ;
		nkMaths::Vector _lightColor = nkMaths::Vector(1.f, 1.f, 1.f) ;
		nkMaths::Vector _albedoColor ;
		nkMaths::Vector _specularColor = nkMaths::Vector(0.5f, 0.5f, 0.5f) ;
		nkMaths::Vector _emissiveColor ;
		nkMaths::Vector _envColor ;

		ShadowMapParameters _shadowMapParameters ;

		nkMemory::String _positionAttributeName = "POSITION" ;
		nkMemory::String _texCoordAttributeName = "TEXCOORD" ;
		nkMemory::String _normalAttributeName = "NORMAL" ;
		nkMemory::String _tangentAttributeName = "TANGENT" ;
		nkMemory::String _binormalAttributeName = "BINORMAL" ;

		unsigned int _albedoColorSlot = 0 ;
		unsigned int _specularColorSlot = 0 ;
		unsigned int _emissiveColorSlot = 0 ;
		unsigned int _envTexInfoSlot = 0 ;
		unsigned int _envColorSlot = 0 ;

		float _metalness = 0.5f ;
		float _roughnessGlossiness = 0.5f ;
		float _alpha = 1.f ;
		float _alphaCutoff = 0.00001f ;
		
		unsigned int _metalnessSlot = 0 ;
		unsigned int _roughnessGlossinessSlot = 0 ;
		unsigned int _alphaSlot = 0 ;

		unsigned int _shadowMapInfoSlot = 0 ;
		unsigned int _shadowLightViewSlot = 0 ;
		unsigned int _shadowLightProjSlot = 0 ;

		// Pointers
		nkGraphics::Texture* _albedoTex = nullptr ;
		nkGraphics::Texture* _specularTex = nullptr ;
		nkGraphics::Texture* _emissiveTex = nullptr ;
		nkGraphics::Texture* _envTex = nullptr ;
		nkGraphics::Texture* _irradianceTex = nullptr ;
		nkGraphics::Texture* _metalnessTex = nullptr ;
		nkGraphics::Texture* _roughnessGlossinessTex = nullptr ;
		nkGraphics::Texture* _alphaTex = nullptr ;
		nkGraphics::Texture* _occlusionTex = nullptr ;
		nkGraphics::Texture* _normalMapTex = nullptr ;
		nkGraphics::Texture* _shadowMapTex = nullptr ;

		nkGraphics::Texture* _textureSlots [8] ;

		nkGraphics::Camera* _shadowMapCamera = nullptr ;

		// Packing
		THREE_CHANNEL_PACK _albedoPacking ;
		THREE_CHANNEL_PACK _specularPacking ;
		THREE_CHANNEL_PACK _emissivePacking ;
		THREE_CHANNEL_PACK _envPacking ;
		THREE_CHANNEL_PACK _irradiancePacking ;
		ONE_CHANNEL_PACK _metalnessPacking ;
		ONE_CHANNEL_PACK _roughnessGlossinessPacking ;
		ONE_CHANNEL_PACK _alphaPacking ;
		ONE_CHANNEL_PACK _occlusionPacking ;
		THREE_CHANNEL_PACK _normalMapPacking ;

		// Model
		PBS_MODEL _pbsModel = PBS_MODEL::SPECULAR_METALNESS_ROUGHNESS ;

		// Loading witnesses for updates
		int _albedoTexSlot = -1 ;
		int _specularTexSlot = -1 ;
		int _emissiveTexSlot = -1 ;
		int _metalnessTexSlot = -1 ;
		int _roughnessGlossinessTexSlot = -1 ;
		int _alphaTexSlot = -1 ;
		int _occlusionTexSlot = -1 ;
		int _normalMapTexSlot = -1 ;
		bool _usingEnvTex = false ;
		bool _prefilteredEnv = false ;
		bool _usingIrradianceTex = false ;

		// Flags
		bool _envTexIsCubeByDefault = true ;
		bool _irradianceTexIsCubeByDefault = true ;
		bool _reconstructBinormals = true ;
		bool _mixAlbedoColorAndTexture = false ;
		bool _mixSpecularColorAndTexture = false ;
		bool _mixEmissiveColorAndTexture = false ;
		bool _mixMetalnessFactorAndTexture = false ;
		bool _mixRoughnessGlossinessFactorAndTexture = false ;
		bool _mixEnvironmentColorAndTexture = false ;
		bool _mixAlphaFactorAndTexture = false ;
		bool _combineLightAndEnvironment = false ;
	} ;
}